#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <pthread.h>
#include <unistd.h>
#include "Mutex.hpp"

using namespace std;

// 1. 多个执行流进行安全访问的共享资源 - 临界资源
// 2. 我们把多个执行流中，访问临界资源的代码 -- 临界区 -- 往往是线程代码的很小的一部分
// 3. 想让多个线程串行访问共享资源 -- 互斥
// 4. 对一个资源进行访问的时候，要么不做，要么做完 -- 原子性 ，一个对资源进行的操作，如果只用一条汇编就能完成
// 反之：不是原子的 -- 当前理解

//共享资源 
int ticket = 10000;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// class ThreadData
// {
// public:
//     //ThreadData(const string name)
//     ThreadData(const string name, pthread_mutex_t* mutex_p)
//         : _name(name)
//         ,_mutex_p(mutex_p)
//     {}
// public:
//     const string _name;
//     pthread_mutex_t* _mutex_p;
// };

class ThreadData
{
public:
    ThreadData(const string name)
        : _name(name)
    {}
public:
    const string _name;
};

void* start(void* args)
{
    //const char* name = static_cast<const char*> (args);
    ThreadData* td= static_cast<ThreadData*>(args);
    while(true)
    {
        {
            LockGuard lockguard(&lock);
            if(ticket > 0)
            {
                usleep(1000);
                cout << td->_name << "正在进行抢票: " << ticket << endl;
                ticket--;
            }
            else
            {
                break;
            }
        }
        usleep(1000);
    }
    return nullptr;
}
int main()
{
#define NUM 4
    vector<pthread_t> tids(NUM);
    for(int i = 0; i < NUM; ++i)
    {
        char buffer[1024];
        snprintf(buffer, sizeof buffer, "thread->%d", i+1);
        // name = buffer;
        // string name = "thread " + to_string(i+1);
        ThreadData* td = new ThreadData(buffer);
        pthread_create(&tids[i], nullptr, start, (void*)td);
    }

    for(auto& tid : tids)
    {
        pthread_join(tid, nullptr);
    }
    return 0;
}
// void *getTicket(void *args)
// {
//     ThreadData *td = static_cast<ThreadData *>(args);
//     while (true)
//     {
//         pthread_mutex_lock(td->_mutex_p);
//         //在lock和unlock直接的就是临界资源，访问临界资源的代码就是临界区
//         //使用锁后就实现了串行，保护了共享资源
//         if (ticket > 0)
//         {
//             usleep(1000);
//             cout << td->_name << " 正在进行抢票: " << ticket << endl;
//             ticket--;
//             pthread_mutex_unlock(td->_mutex_p);
//         }
//         else
//         {
//             pthread_mutex_unlock(td->_mutex_p);
//             break;
//         }
//         //模拟抢到票后的其他事情
//         usleep(1000);
//     }

//     return nullptr;
// }

// int main()
// {
// #define NUM 4
//     //创建锁
//     static pthread_mutex_t lock;
//     //初始化
//     pthread_mutex_init(&lock, nullptr);

//     vector<pthread_t> tids(NUM);
//     for (int i = 0; i < NUM; ++i)
//     {
//         char buffer[64];
//         snprintf(buffer, sizeof(buffer), "thread->%d", i + 1);
//         //ThreadData *td = new ThreadData(buffer);
//         ThreadData *td = new ThreadData(buffer, &lock);

//         pthread_create(&tids[i], nullptr, getTicket, (void *)td);
//     }

//     for(const auto& tid : tids)
//     {
//         pthread_join(tid, nullptr);
//     }

//     pthread_mutex_destroy(&lock);
//     return 0;
// }



// void *getTicket(void *args)
// {
//     ThreadData *td = static_cast<ThreadData *>(args);
//     while (true)
//     {
//         {
//             LockGuard lockguard(td->_mutex_p);
//             //在lock和unlock直接的就是临界资源，访问临界资源的代码就是临界区
//             //使用锁后就实现了串行，保护了共享资源
//             if (ticket > 0)
//             {
//                 usleep(1000);
//                 cout << td->_name << " 正在进行抢票: " << ticket << endl;
//                 ticket--;
//             }
//             else
//             {
//                 break;
//             }
//         }
        
//         //模拟抢到票后的其他事情
//         usleep(1000);
//     }

//     return nullptr;
// }

// int main()
// {
// #define NUM 4
//     //创建锁
//     static pthread_mutex_t lock;
//     //初始化
//     pthread_mutex_init(&lock, nullptr);

//     vector<pthread_t> tids(NUM);
//     for (int i = 0; i < NUM; ++i)
//     {
//         char buffer[64];
//         snprintf(buffer, sizeof(buffer), "thread->%d", i + 1);
//         //ThreadData *td = new ThreadData(buffer);
//         ThreadData *td = new ThreadData(buffer, &lock);

//         pthread_create(&tids[i], nullptr, getTicket, (void *)td);
//     }

//     for(const auto& tid : tids)
//     {
//         pthread_join(tid, nullptr);
//     }

//     pthread_mutex_destroy(&lock);
//     return 0;
// }

// int ticket = 10000;

// pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// void *getTicket(void *args)
// {
//     // other code
//     std::string username = static_cast<const char *>(args);
//     while (true)
//     {
//         {
//             LockGuard lockguard(&lock); // RAII风格的加锁！
//             if (ticket > 0)
//             {
//                 usleep(1000); // 1秒 = 1000毫秒 = 1000 000 微妙 = 10^9纳秒
//                 std::cout << username << " 正在进行抢票: " << ticket << std::endl;
//                 ticket--;
//             }
//             else
//             {
//                 break;
//             }
//         }
//         usleep(1000); 
//     }

//     return nullptr;
// }

// int main()
// {
// #define NUM 4
//     vector<pthread_t> tids(NUM);
//     for (int i = 0; i < NUM; ++i)
//     {
//         char buffer[64];
//         snprintf(buffer, sizeof(buffer), "thread->%d", i + 1);

//         pthread_create(&tids[i], nullptr, getTicket, (void *)buffer);
//     }

//     for(const auto& tid : tids)
//     {
//         pthread_join(tid, nullptr);
//     }
//     return 0;
// }